package name.luojun.DBhelper;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import name.luojun.DBhelper.iface.UpgradeSupport;
import name.luojun.DBhelper.model.Column;
import name.luojun.DBhelper.model.TableVO;

import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
@SuppressWarnings("rawtypes")
public class MappedUpgradeSupport extends UpgradeSupport {
	private String table;
	private String rule;
	public String getTable() {
		return table;
	}
	public void setTable(String table) {
		this.table = table.toUpperCase();
		this.tableVO = TableManager.tableMap.get(this.table);
		if (this.tableVO == null) {
			throw new RuntimeException("there is no mapped table '" + table + "'");
		}
		try {
			if (tableVO.getClassname() != null) {
				cls = Class.forName(tableVO.getClassname());
			}
		} catch (ClassNotFoundException e) {
			throw new RuntimeException(e);
		}
	}
	private String getAll;
	private String insert;
	private String modify;
	private String delete;
	protected Class<?> cls;
	private TableVO tableVO;
	private int insertcount = 0;
	private int deletecount = 0;
	private int modifycount = 0;
	@Override
	public void initDao() {
		if (this.table == null || this.table.trim().length() == 0) {
			throw new RuntimeException("property table is required");
		}
		this.init();
		try {
			if (filePath == null || filePath.length() == 0) {
				throw new RuntimeException("property filePath should not be null!");
			}
			doUpgrade();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	private void init() {
		StringBuffer getbuffer = new StringBuffer();
		StringBuffer insertbuffer = new StringBuffer();
		StringBuffer modifybuffer = new StringBuffer();
		StringBuffer deletebuffer = new StringBuffer();
		StringBuffer insv = new StringBuffer();
		getbuffer.append("select ");
		insertbuffer.append("insert into " + tableVO.getName() + " (");
		modifybuffer.append("update " + tableVO.getName() + " set ");
		deletebuffer.append("delete from " + tableVO.getName() + " where ");
		Map<String, Column> cols = tableVO.getColumns();
		for (Entry<String, Column> en : cols.entrySet()) {
			Column col = en.getValue();
			getbuffer.append(col.getName() + " as " + col.getField() + ",");
			insertbuffer.append(col.getName() + ",");
			if (col.getGenerator() != null && col.getGenerator().equalsIgnoreCase("sequence")) {
				insv.append(col.getSequence() + ".NEXTVAL ,");
			} else
				insv.append(":" + col.getField() + ",");
			modifybuffer.append(col.getName() + "=:" + col.getField() + ",");
		}
		modifybuffer.deleteCharAt(modifybuffer.length() - 1);
		insertbuffer.deleteCharAt(insertbuffer.length() - 1);
		insv.deleteCharAt(insv.length() - 1);
		getbuffer.deleteCharAt(getbuffer.length() - 1);
		insertbuffer.append(") values (" + insv + ")");
		getbuffer.append(" from " + tableVO.getName());
		this.getAll = getbuffer.toString();
		this.insert = insertbuffer.toString();
		modifybuffer.append(" where ");
		for (String str : tableVO.getPk()) {
			Column col = cols.get(str);
			modifybuffer.append(col.getName() + "=:" + col.getField() + " and ");
			deletebuffer.append(col.getName() + "=:" + col.getField() + " and ");
		}
		modifybuffer.delete(deletebuffer.length() - 5, deletebuffer.length() - 1);
		deletebuffer.delete(deletebuffer.length() - 5, deletebuffer.length() - 1);
		this.modify = modifybuffer.toString();
		this.delete = deletebuffer.toString();
	}
	@Override
	public List getAll() {
		return this.getJdbcTemplate().query(getAll, new BeanPropertyRowMapper(cls));
	}
	@Override
	public void insert(Object e) {
		insertcount++;
		this.getNamedParameterJdbcTemplate().update(insert, new BeanPropertySqlParameterSource(e));
	}
	@Override
	public void modify(Object e) {
		modifycount++;
		this.getNamedParameterJdbcTemplate().update(modify, new BeanPropertySqlParameterSource(e));
	}
	@Override
	public void delete(Object e) {
		deletecount++;
		this.getNamedParameterJdbcTemplate().update(delete, new BeanPropertySqlParameterSource(e));
	}
	@Override
	public String getRule() {
		return this.rule == null ? UpgradeManager.INSERTORUPDATE : this.rule;
	}
	@Override
	public String[] getPrimaryKey() {
		String[] pk = new String[tableVO.getPk().size()];
		for (int i = 0; i < pk.length; i++) {
			String str = tableVO.getPk().get(i);
			pk[i] = tableVO.getColumns().get(str).getField();
		}
		return pk;
	}
	@Override
	public String[] getFields() {
		return UpgradeManager.getFileds(cls);
	}
	public void setRule(String rule) {
		this.rule = rule;
	}
	@Override
	public void doUpgrade() {
		try {
			File file = new File(filePath);
			if (!file.exists()) {
				log.error("file not exist," + table + " upgrade stoped,path:" + filePath);
				return;
			}
			UpgradeManager.FileUpgrade(this, this.cls, Object.class, this.getInputStream(), "getAll", "insert", "modify", "delete",
					this.getPrimaryKey(), this.getFields(), this.getRule());
			deleteFile();
			log.info(table + " upgrade finished, insert " + insertcount + " records ,delete " + deletecount + " records ,update "
					+ modifycount + " records");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}
